#ifndef _DSWTCPCLIENT_BASE_H
#define _DSWTCPCLIENT_BASE_H

#include <libbase/dswbase.h>

#define MAKEMSGHEAD_V2(x, y, z){x.SetDoc(XMLFLAG);x.AddElem("Message");x.AddAttrib("CID", y);x.AddAttrib("Verison", XMLVER);x.AddAttrib("MsgType", z);}
#define MAKEMSGHEAD_V1(x, y, z)	{x.SetDoc("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");x.AddElem("Message");x.AddAttrib("Version", XMLVER_1);x.IntoElem();x.AddElem("DSW_HEADER");x.IntoElem();x.AddElem("MessageType", y);x.OutOfElem();x.AddElem("PUA_ID", z);x.OutOfElem();}
#define MAKEMSGHEAD_V1_P2P_REQ(x, y, z, c)	{x.SetDoc("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");x.AddElem("Message");x.AddAttrib("Version", XMLVER_1);x.IntoElem();x.AddElem("DSW_HEADER");x.IntoElem();x.AddElem("MessageType", y);x.OutOfElem();x.AddElem("PUC_ID", z);x.AddElem("P2P_MSGS");x.IntoElem();x.AddSubDoc(c);x.OutOfElem();x.OutOfElem();}

#define WANMSG_SESSION_HEADSIZE 3
#define LANMSG_SESSION_HEADSIZE 4
#define AV_SESSION_HEADSIZE 5

typedef bool (*CB_MSG_FUNC)(char* pCallID, void* pReqMsg, const char* sMsgIDResp, void* pCaller);
typedef struct{
	const char* sMsgReq;
	const char* sMsgIDResp;
	CB_MSG_FUNC pP2PFunc;
} ST_P2PMSG_T, *LPST_P2PMSG_T;

typedef enum{
	MISSION_UNKNOW,
	MISSION_CENTER,
	MISSION_REGISTER,
	MISSION_ALARM,
	MISSION_WAN_MSG,
	MISSION_FWD,
} EN_MISSION_TYPE;

#define RXBUF_SIZE (1024 * 1024)

class CDswtcpclient_base : public CDswbase
{
public:
	CDswtcpclient_base(LPST_ENV_T pEnv, struct event_base *base, int nfd, int nWantReadLen);
	CDswtcpclient_base(LPST_ENV_T pEnv, char* pHost, int nPort);
	virtual ~CDswtcpclient_base();
protected:
	static void cbConnectTaskFunc(int fd, short events, void* ctx){((CDswtcpclient_base*)ctx)->ConnectTaskFunc(fd, events);};
	void ConnectTaskFunc(int fd, short events);
	static void cb_OnEvent(struct bufferevent *bev, short events, void *ctx){((CDswtcpclient_base*)ctx)->OnEvent(bev, events);};
	static void cb_OnRead(struct bufferevent *bev, void *ctx){((CDswtcpclient_base*)ctx)->OnRead(bev);};
	static void cb_OnWrite(struct bufferevent *bev, void *ctx){((CDswtcpclient_base*)ctx)->OnWrite(bev);};

	static void cbDNSRequestTaskFunc(int fd, short events, void* ctx){((CDswtcpclient_base*)ctx)->DNSRequestTaskFunc(fd, events);};
	void DNSRequestTaskFunc(int fd, short events);

	static void cbOnDnsRequest(int errcode, struct evutil_addrinfo *addr, void *ptr){((CDswtcpclient_base*)ptr)->OnDnsRequest(errcode, addr);};
	void OnDnsRequest(int errcode, struct evutil_addrinfo *addr);
	
protected:
	virtual void OnWrite(struct bufferevent *bev){};
	virtual void OnEvent(struct bufferevent *bev, short events);
	virtual void ReConnect(int nSecond, int nUSecond);
	virtual void OnError(struct bufferevent *bev, short events){};
	virtual void OnConnect(struct bufferevent *bev, short events);
	virtual void OnRead(struct bufferevent *bev);
	virtual int MakePayloadLength(char* pData, int nLen){return 0;};
	virtual bool ProcessMessage(char* pMsg, int nLen, struct evbuffer *outbuf){return false;};
	virtual bool PrePressError(struct bufferevent *bev, short events){return false;};
protected:
	char m_sHost[256];
	char m_sIpAddr[64];
	int m_nPort;
	ST_TIMER_PARAM_T m_nConnectTask, m_nDNSRequestTask;
	struct bufferevent *m_pBev;
	int m_nPayloadLen, m_nWantReadLen;
	char* m_pRxBuffer;
};

#endif

